package com.emmmya.utils.exprossion;

import com.emmmya.executor.DefaultExecutor;
import com.emmmya.harinCheck.engine.AbsHarinCheckEngine;
import com.emmmya.harinCheck.utils.HarinStringUtils;
import com.emmmya.harinCheck.utils.RegexUtils;
import com.emmmya.pojo.excel.ExcelAutoPack;
import org.apache.poi.ss.usermodel.Cell;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author Harin
 * @version 1.0
 * @date 2022-05-07 16:35:26
 */
public class ExcelExprossionUtils extends ExprossionUtils {

    /**
     *
     * @param source                源对象
     * @param cell                  当前待处理的单元格
     * @param fieldName             属性名
     * @param methodsMap            过滤器函数集合
     * @return
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    public static Object getExprossionValue(Object source, Cell cell, String fieldName, Map<String, Method> methodsMap) {
        //切割过滤器
        Map<String, Object> paramAndFunMap = splitFilterFunction(fieldName);
        //获取（单个或链式）属性的值，作为过滤器的第一个参数传入
        Object exprossionValue = getExprossionValue(source, (String)paramAndFunMap.get(LAST_FIELD_NAME));
        if(paramAndFunMap!= null && paramAndFunMap.size() > 0) {
            if (methodsMap != null && methodsMap.size() > 0) {
                //获取其余参数
                List<String> filterFunList = (List<String>)paramAndFunMap.get(FITLER_FUN_LIST);
                if(filterFunList!= null){
                    try {
                        //使用临时变量存储第一个参数
                        Object paramTempObj = exprossionValue;
                        ArrayList<Object> params = new ArrayList<>();

                        //便利过滤器
                        for (String filterFunStr : filterFunList) {
                            params.clear();;
                            List<Object> filterFunParams = getFilterFunParams(paramTempObj, source, filterFunStr,",");

                                params.add(paramTempObj);
                                //补全参数到params中
                                params.addAll(params.size(), filterFunParams);
                                //匹配对应的过滤器（全局匹配：先匹配传入的函数集，在判断系统内置函数集）
                                Method method = matchingFunction(methodsMap, filterFunStr,params);
                                //如果是excelUtils传入的函数，则需要传入cell作为参数
                                if(method == null){
                                    params.clear();
                                    params.add(paramTempObj);
                                    params.add(cell);
                                    params.addAll(params.size(), filterFunParams);
                                    method = matchingFunction(methodsMap, filterFunStr,params);
                                }
                                if(method != null) {
                                    //调用方法
                                    Object o = DefaultExecutor.executeMethod(method, params.toArray());
                                    if (o != null) {
                                        paramTempObj = o;       //作为下个过滤器参数
                                        exprossionValue = o;
                                    }
                                }

                        }
                    }catch (Exception e){e.printStackTrace();}
                }
            }
        }
        return exprossionValue;
    }


    /**
     * 解析
     * @param cell
     * @param param
     * @param methodsMap
     * @return          如果param不是字符串，则直接返回param，如果不存在过滤器，直接返回param
     */
    public static Object parseExcelFunction(Cell cell,Object param, Map<String, Method> methodsMap){
        ArrayList<Object> filterParams = new ArrayList<>();
            if(!(param instanceof String)) return param;
            Map<String, Object> stringObjectMap = splitFilterFunction((String)param);
            List<String> filterFunList = (List<String>) stringObjectMap.get(FITLER_FUN_LIST);
            if (filterFunList != null) {
                try {
                    String lastParam = (String)stringObjectMap.get(LAST_FIELD_NAME);
                    Object source = null;
                    //这要使用一个实体类来获取
                    if(lastParam.contains("this.cell")){
                        source = cell;
                    }else if(lastParam.contains("this.row")){
                        source = cell.getRow();
                    }

                    for (String filterFunStr : filterFunList) {
                        filterParams.clear();
                        //匹配对应的过滤器（全局匹配：先匹配传入的函数集，在判断系统内置函数集）
                        //Method method = matchingFunction(methodsMap, filterFunStr);
                        List<Object> filterFunParams = getFilterFunParams(null, null, filterFunStr, ",");
                        filterParams.add(source);
                        //补全参数到params中
                        if(filterFunParams!= null && filterFunParams.size() > 0) {
                            filterParams.addAll(filterParams.size(), filterFunParams);
                        }
                        Method method = matchingFunction(methodsMap, filterFunStr,filterParams);
                        source = DefaultExecutor.executeMethod(method, filterParams.toArray());
                        //return o;
                    }
                    return source;
                } catch (Exception e) {
                    e.printStackTrace();
                }
        }
        return param;
    }

    /**
     * 匹配参数
     * @param paramStr          过滤器函数中参数
     * @param separator         分隔符号
     * @return
     */
    public static List<Object> parseExcelFunctionParam(String paramStr,String separator){
        String tempStr = String.copyValueOf(paramStr.toCharArray());

        String[] paramArray = tempStr.split(separator);
        List<Object> params = new ArrayList<>();
        for (int i = 0; i < paramArray.length; i++) {
            String param = paramArray[i].trim();
            //先判断是否为数字
            boolean any = RegexUtils.findAny(AbsHarinCheckEngine.NUMBER_PATTERN,param);
            if(any){
                BigDecimal paramBigTemp = new BigDecimal(param);
                if(param.contains(".")) {
                    params.add((Double)paramBigTemp.doubleValue());
                }else{
                    params.add((Integer)paramBigTemp.intValue());
                }
            }else {
                params.add(param);
            }
        }
        return params;

    }


    /**
     * 增强版获取属性的值
     */
    public static Object getFieldValueEnhanced(Object o, String colName, ExcelAutoPack eap){
        Object fieldValue = getFieldValue(o, colName);
        if(fieldValue instanceof Date){
            String dataFormat = eap.getDataFormat();
            if(HarinStringUtils.isEmpty(dataFormat)){
                dataFormat = "yyyy-MM-dd HH:mm:ss";
            }
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dataFormat);
            fieldValue = simpleDateFormat.format(fieldValue);
        }
        return fieldValue;
    }

}
